// Copyright 2008 Senary
// See credits.txt for details.

// This file is part of Omega VII.

// Omega VII is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Omega VII is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Omega VII.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include "Angle.h"
#include "Vector.h"
#include "Constants.h"

class SpaceObject;

const double CAMERA_NORMAL_SPEED = 1000.0;
const double CAMERA_ZOOM_SPEED = 1000.0;
const double CAMERA_MAX_SPEED = 2.0 * CAMERA_NORMAL_SPEED;
const double CAMERA_TARGET_DISTANCE = 5.0 * AU_IN_QUANTS;
const double CAMERA_TARGET_MIN_DISTANCE = CAMERA_TARGET_DISTANCE * 0.2;

class Camera
{
protected:
	// Together, the position of the camera relative to the origin,
	// _upwards and _right establish the right-handed coordinate
	// system of the camera.
	
	// camera will rotate around this origin, and always look towards it
	Vector _origin;

	// current position of the camera
	Vector _position;

	// upwards direction of the camera
	Vector _upwards;

	// right direction of the camera
	Vector _right;

	// target position of the camera
	Vector _targetPosition;

	// Minimum and maximum distance of the camera from the origin
	double _minRadius;
	double _maxRadius;

	// If not null, the camera will follow this object
	SpaceObject * _target;

	// if the camera follows an object, what distance do we have to it?
	double _targetDistance;

public:
	Camera(Vector origin = Vector());
	~Camera(void);

	//get Angle
	Angle getAngle(void) const;
	//get Position
	Vector const& getPosition(void) const;
	//getter for origin
	Vector const& getOrigin(void) const;
	// getter for the target
	SpaceObject* getTarget() const;

	//setter for position, camera orientatio will be updated automatically
	void setPosition(Vector position);
	// setter for origin
	void setOrigin(Vector origin);
	// boundary of zoom in and zoom out
	void setBoundary(double minRadius, double maxRadius);
	// Sets the target to the specified SpaceObject and starts moving towards it
	void setTarget(SpaceObject* target);

	//translation movement
	// Moves the camera in the specified direction
	// This will disable following of any target.
	void move(int up, int right, int down, int left, float timestep);

	//positive value = zoom out, negative value = zoom in
	void zoom(double distance, float timestep);

	// Update the camera, that is, move towards the target
	void update(float timestep, float totalTime);
};
